'use strict'
const KoaRouter = require('koa-router')
const controller = require( '../controller')
const co = require('co')
const {isGeneratorFunction , isObject, isArray ,isResponseCode,isPromise} = require('../common')

module.exports = (app) => {
    let router = KoaRouter(app)
    let root = '/'
    for(let _ in controller) {
        for(let __ in controller[_]) {
            if(typeof controller[_][__] === 'function') {
                let path = root + _ + '/' + __
                router.all(path, async (ctx, next) =>{
                    let res = {}
                    res.request = ctx.request
                    if(isGeneratorFunction(controller[_][__])) {
                        let gen = controller[_][__](ctx,next)
                        let it = null
                        let isok = false,retType = 'fetch'
                        let _next = async (err, next) => {
                            if(err) res = err
                            it = gen.next(res)
                            let _val = it.value
                            let processData = async (v1) => {
                                if(isObject(v1)) {
                                    switch(v1.opts) {
                                        case 0:
                                            ctx.response.set(v1.key, v1.value)
                                            break
                                        case 1:
                                            res[v1.key] =  v1.value
                                            break
                                        case 2:
                                            if(v1.value)
                                                Object.assign(res, v1.value)
                                            if(v1.key === 'json') {
                                                ctx.type = 'json'
                                            }
                                            isok = true
                                            break
                                        case 3:
                                            ctx.response.redirect(v1.value)
                                            isok = true
                                            break
                                        case 4:
                                            ctx.cookies.set(v1.key, v1.value, v1.options?v1.options:{})
                                            break
                                    }
                                }else if(isResponseCode(v1)){
                                    ctx.response.status = v1
                                }else if(isPromise(v1)){
                                    let vx = await v1
                                    console.log(vx)
                                    await processData(vx)
                                }else {
                                    //throw '程序错误'
                                }
                            }

                            await processData(_val)
                            if(it.done || isok) {
                                if(ctx.type === 'application/json') {
                                    ctx.body = JSON.stringify(res)
                                }else if(ctx.type === 'image/png') {

                                }else{
                                    await ctx.render('.' + path, res)
                                }
                            }else {
                                await _next()
                            }
                        }
                        await _next()
                    }else {
                        res = controller[_][__](ctx,next)
                        if (ctx.req.headers['x-requested-with']&&ctx.req.headers['x-requested-with'].toLowerCase() == 'xmlhttprequest') {
                            ctx.type = 'json'
                            ctx.body = JSON.stringify(res)
                        }else {
                            await ctx.render('.' + path, res)
                        }
                    }
                })
            }
        }
    }
    return router.routes()
}